package com.lzw.DailyAudit.service.dateAggregation_02.DailyAudit.service.issueReports_04;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.EasyExcel;
import com.hooya.fa.eu.biz.DailyAudit.entity.dto.InoutExcelDTO;
import com.hooya.fa.eu.biz.DailyAudit.entity.dto.InvoiceDataDTO;
import com.hooya.fa.eu.biz.DailyAudit.mapper.*;
import com.hooya.fa.eu.biz.DailyAudit.service.dateAggregation_02.CommonService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class Inout {

    @Autowired
    private DailyStkOrigDataCollectMapper dailyStkOrigdataCollectMapper;

    @Autowired
    private DailyMetaStkShipmentMapper dailyMetaStkShipmentMapper;

    @Autowired
    private DailyMetaProductMapper dailyMetaProductMapper;

    @Autowired
    private DailyMetaCorpHeaderMapper dailyMetaCorpHeaderMapper;

    @Autowired
    private CommonService commonService;

    /**
     * 主方法
     */
    public void inout(String currentDate, String belong, String country) {
        try {

            // 计算结束日期
            String[] split = currentDate.split("-");
            if (split.length != 3) {
                log.error("日期格式有误！");
                return;
            }
            String year = split[0];
            String month = split[1];
            String day = split[2];
            LocalDate startDate = LocalDate.parse(currentDate, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
            LocalDate endDate = startDate.plusDays(1);
            String end = endDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));


            Map<String, List<InvoiceDataDTO>> generateData = generateData(currentDate, end, belong, country);
            List<InvoiceDataDTO> fromData = generateData.get("from_data");
            List<InvoiceDataDTO> toData = generateData.get("to_data");

            List<InvoiceDataDTO> finalFromData = addInfos(fromData, currentDate, belong);
            List<InvoiceDataDTO> finalToData = addInfos(toData, currentDate, belong);

            //整理数据 -- 空值处理
            handleData(finalFromData);
            handleData(finalToData);

            //  创建目录并生成Excel文件
            String dir = "./inout/" + year + "/" + month + "/" + day;
            String fromDir = String.format(dir + "/%s_inout_list/from_%s", belong, country.toLowerCase());
            String toDir = String.format(dir + "/%s_inout_list/to_%s", belong, country.toLowerCase());

            // 创建目录
            commonService.createDirectories(fromDir);
            commonService.createDirectories(toDir);

            // 生成Excel文件
            String fromFilePath = String.format("%s/%s.xlsx", fromDir, startDate);
            String toFilePath = String.format("%s/%s.xlsx", toDir, startDate);

            generateExcelFile(finalFromData, fromFilePath, "fromFile");
            generateExcelFile(finalToData, toFilePath, "toFile");

            log.info("处理InOut数据完成");
        } catch (Exception e) {
            log.error("处理InOut数据时发生错误", e);
            throw new RuntimeException("处理InOut数据时发生错误", e);
        }
    }

    /**
     * 处理空值数据
     *
     * @param Data
     */
    private void handleData(List<InvoiceDataDTO> Data) {
        Data.forEach(f -> {
            f.setHscode(f.getHscode() != null ? f.getHscode() : "");
            f.setB(f.getB() != null ? f.getB() : "");
            f.setLocation(f.getLocation() != null ? f.getLocation() : "");
            f.setBirthplace(f.getBirthplace() != null ? f.getBirthplace() : "");
            f.setWeight(f.getWeight() != null ? f.getWeight() : 0.0);
            f.setQty(f.getQty() != null ? f.getQty() : 0);
            f.setPrice(f.getPrice() != null ? f.getPrice() : 0.0);
            f.setBuyerTaxId(f.getBuyerTaxId() != null ? f.getBuyerTaxId() : "");
            f.setInvoiceNo(f.getInvoiceNo() != null ? f.getInvoiceNo() : "");
            f.setDate(f.getDate() != null ? f.getDate() : "");
            f.setSku(f.getSku() != null ? f.getSku() : "");
        });
    }

    /**
     * 生成Excel文件
     *
     * @param data      数据列表
     * @param filePath  文件路径
     * @param sheetName sheet名称
     */
    private void generateExcelFile(List<InvoiceDataDTO> data, String filePath, String sheetName) {
        try {
            // 将InvoiceDataDTO转换为InoutExcelDTO
            List<InoutExcelDTO> excelData = data.stream().map(item -> {
                InoutExcelDTO excelItem = new InoutExcelDTO();
                BeanUtil.copyProperties(item, excelItem);
                return excelItem;
            }).collect(Collectors.toList());

            // 使用EasyExcel写入文件
            EasyExcel.write(filePath, InoutExcelDTO.class)
                    .sheet(sheetName)
                    .doWrite(excelData);

            log.info("文件生成完成");
        } catch (Exception e) {
            log.error("生成Excel文件失败: {}", filePath, e);
            throw new RuntimeException("生成Excel文件失败: " + filePath, e);
        }
    }

    /**
     * 处理B2B数据
     */
    public Map<String, List<InvoiceDataDTO>> dealB2b(String start, String end, String belong, String country) {
        Map<String, List<InvoiceDataDTO>> result = new HashMap<>();

        // 获取B2B数据
        List<InvoiceDataDTO> b2b = dailyStkOrigdataCollectMapper.getB2bDataByBelong(start, end, belong);

        // 处理 b2b_from 数据
        List<InvoiceDataDTO> b2bFrom = b2b.stream()
                .filter(dto -> belong.equals(dto.getSeller()))
                .filter(dto -> "out".equals(dto.getDirection()))
                .filter(dto -> !country.equals(dto.getTocountry()))
                .collect(Collectors.toList());

        b2bFrom = addTaxid(b2bFrom);
        b2bFrom.forEach(dto -> {
            if (dto.getBuyerTaxId() == null) {
                dto.setBuyerTaxId("");
            }
        });

        // 按sku, 发票号I, 价格G, 目的地C, 买方税号H分组并汇总数量F
        Map<String, List<InvoiceDataDTO>> groupedB2bFrom = b2bFrom.stream()
                .collect(Collectors.groupingBy(dto ->
                        dto.getSku() + "|" + dto.getInvoiceNo() + "|" + dto.getPrice() + "|" +
                                dto.getTocountry() + "|" + dto.getBuyerTaxId()));

        List<InvoiceDataDTO> processedB2bFrom = new ArrayList<>();
        for (Map.Entry<String, List<InvoiceDataDTO>> entry : groupedB2bFrom.entrySet()) {
            List<InvoiceDataDTO> group = entry.getValue();
            InvoiceDataDTO first = group.get(0);
            InvoiceDataDTO newItem = new InvoiceDataDTO();
            BeanUtil.copyProperties(first, newItem);

            // 汇总数量
            int totalQty = group.stream()
                    .mapToInt(dto -> dto.getQty() != null ? dto.getQty() : 0)
                    .sum();
            newItem.setQty(totalQty);

            // 去重处理 -- 根据sku+invoiceId+sku+invoiceNo
            if (processedB2bFrom.stream().noneMatch(item ->
                    Objects.equals(item.getSku(), newItem.getSku()) &&
                            Objects.equals(item.getInvoiceId(), newItem.getInvoiceId()) &&
                            Objects.equals(item.getTocountry(), newItem.getTocountry()) &&
                            Objects.equals(item.getInvoiceNo(), newItem.getInvoiceNo()))) {
                newItem.setB(""); // B列设为空
                newItem.setBirthplace("CN"); // 原产地D设为CN
                processedB2bFrom.add(newItem);
            }
        }

        // 处理 b2b_to 数据
        List<InvoiceDataDTO> b2bTo = b2b.stream()
                .filter(dto -> belong.equals(dto.getBuyer()))
                .filter(dto -> "in".equals(dto.getDirection()))
                .filter(dto -> !country.equals(dto.getFromcountry()))
                .collect(Collectors.toList());

        // 按sku, 发票号I, 价格G, 发车地C分组并汇总数量F
        Map<String, List<InvoiceDataDTO>> groupedB2bTo = b2bTo.stream()
                .collect(Collectors.groupingBy(dto ->
                        dto.getSku() + "|" + dto.getInvoiceNo() + "|" + dto.getPrice() + "|" + dto.getFromcountry()));

        List<InvoiceDataDTO> processedB2bTo = new ArrayList<>();
        for (Map.Entry<String, List<InvoiceDataDTO>> entry : groupedB2bTo.entrySet()) {
            List<InvoiceDataDTO> group = entry.getValue();
            InvoiceDataDTO first = group.get(0);
            InvoiceDataDTO newItem = new InvoiceDataDTO();
            BeanUtil.copyProperties(first, newItem);

            // 汇总数量
            int totalQty = group.stream()
                    .mapToInt(dto -> dto.getQty() != null ? dto.getQty() : 0)
                    .sum();
            newItem.setQty(totalQty);

            // 去重处理 -- 根据sku+invoiceId+sku+invoiceNo
            if (processedB2bTo.stream().noneMatch(item ->
                    Objects.equals(item.getInvoiceId(), newItem.getInvoiceId()) &&
                    Objects.equals(item.getSku(), newItem.getSku()) &&
                            Objects.equals(item.getInvoiceNo(), newItem.getInvoiceNo()))) {
                newItem.setB(""); // B列设为空
                newItem.setBuyerTaxId(""); // 买方税号H设为空
                newItem.setBirthplace("CN"); // 原产地D设为CN
                processedB2bTo.add(newItem);
            }
        }

        // 并且转运数据的invoiceNo 不能为空
        processedB2bFrom = processedB2bFrom.stream().filter(f -> StrUtil.isNotBlank(f.getInvoiceNo())).collect(Collectors.toList());
        processedB2bTo = processedB2bTo.stream().filter(f -> StrUtil.isNotBlank(f.getInvoiceNo())).collect(Collectors.toList());


        result.put("b2b_from", processedB2bFrom);
        result.put("b2b_to", processedB2bTo);
        return result;
    }

    /**
     * 处理采购数据
     */
    public List<InvoiceDataDTO> dealCg(String start, String end, String belong) {
        List<InvoiceDataDTO> cgTo = dailyStkOrigdataCollectMapper.getCgDataByBelong(start, end, belong);

        // 按sku, 发票号I, 价格G分组并汇总数量F
        Map<String, List<InvoiceDataDTO>> groupedCgTo = cgTo.stream()
                .collect(Collectors.groupingBy(dto ->
                        dto.getSku() + "|" + dto.getInvoiceNo() + "|" + dto.getPrice()));

        List<InvoiceDataDTO> processedCgTo = new ArrayList<>();
        for (Map.Entry<String, List<InvoiceDataDTO>> entry : groupedCgTo.entrySet()) {
            List<InvoiceDataDTO> group = entry.getValue();
            InvoiceDataDTO first = group.get(0);
            InvoiceDataDTO newItem = new InvoiceDataDTO();
            BeanUtil.copyProperties(first, newItem);

            // 汇总数量
            int totalQty = group.stream()
                    .mapToInt(dto -> dto.getQty() != null ? dto.getQty() : 0)
                    .sum();
            newItem.setQty(totalQty);

            // 去重处理 -- 根据sku+invoiceId+sku+invoiceNo
            if (processedCgTo.stream().noneMatch(item ->
                    Objects.equals(item.getInvoiceId(), newItem.getInvoiceId()) &&
                            Objects.equals(item.getSku(), newItem.getSku()) &&
                            Objects.equals(item.getInvoiceNo(), newItem.getInvoiceNo()))) {
                newItem.setB(""); // B列设为空
                newItem.setBuyerTaxId(""); // 买方税号H设为空
                newItem.setFromcountry("CN"); // 发车地C设为CN
                newItem.setBirthplace("CN"); // 原产地D设为CN
                processedCgTo.add(newItem);
            }
        }

        // 并且转运数据的invoiceNo 不能为空
        processedCgTo = processedCgTo.stream().filter(f -> StrUtil.isNotBlank(f.getInvoiceNo())).collect(Collectors.toList());

        return processedCgTo;
    }

    /**
     * 处理转运数据
     */
    public Map<String, List<InvoiceDataDTO>> dealZy(String start, String end, String belong, String country) {
        Map<String, List<InvoiceDataDTO>> result = new HashMap<>();

        // 获取转运数据
        List<InvoiceDataDTO> zy = dailyStkOrigdataCollectMapper.getZyDataByBelong(start, end, belong);

        // 处理 zy_from 数据
        List<InvoiceDataDTO> zyFrom = zy.stream()
                .filter(dto -> belong.equals(dto.getSeller()))
                .filter(dto -> "out".equals(dto.getDirection()))
                .filter(dto -> !country.equals(dto.getTocountry()))
                .collect(Collectors.toList());

        zyFrom = addTaxid(zyFrom);
        zyFrom.forEach(dto -> {
            if (dto.getBuyerTaxId() == null) {
                dto.setBuyerTaxId("");
            }
        });

        // 按sku, 发票号I, 价格G, 目的地C, 买方税号H分组并汇总数量F
        Map<String, List<InvoiceDataDTO>> groupedZyFrom = zyFrom.stream()
                .collect(Collectors.groupingBy(dto ->
                        dto.getSku() + "|" + dto.getInvoiceNo() + "|" + dto.getPrice() + "|" +
                                dto.getTocountry() + "|" + dto.getBuyerTaxId()));

        List<InvoiceDataDTO> processedZyFrom = new ArrayList<>();
        for (Map.Entry<String, List<InvoiceDataDTO>> entry : groupedZyFrom.entrySet()) {
            List<InvoiceDataDTO> group = entry.getValue();
            InvoiceDataDTO first = group.get(0);
            InvoiceDataDTO newItem = new InvoiceDataDTO();
            BeanUtil.copyProperties(first, newItem);

            // 汇总数量
            int totalQty = group.stream()
                    .mapToInt(dto -> dto.getQty() != null ? dto.getQty() : 0)
                    .sum();
            newItem.setQty(totalQty);

            // 去重处理 -- 根据sku+invoiceId+sku+invoiceNo
            if (processedZyFrom.stream().noneMatch(item ->
                    Objects.equals(item.getInvoiceId(), newItem.getInvoiceId()) &&
                            Objects.equals(item.getSku(), newItem.getSku()) &&
                            Objects.equals(item.getInvoiceNo(), newItem.getInvoiceNo()))) {
                newItem.setB(""); // B列设为空
                newItem.setBirthplace("CN"); // 原产地D设为CN
                processedZyFrom.add(newItem);
            }
        }

        // 处理 zy_to 数据
        List<InvoiceDataDTO> zyTo = zy.stream()
                .filter(dto -> belong.equals(dto.getBuyer()))
                .filter(dto -> "in".equals(dto.getDirection()))
                .filter(dto -> !country.equals(dto.getFromcountry()))
                .collect(Collectors.toList());

        // 按sku, 发票号I, 价格G, 发车地C分组并汇总数量F
        Map<String, List<InvoiceDataDTO>> groupedZyTo = zyTo.stream()
                .collect(Collectors.groupingBy(dto ->
                        dto.getSku() + "|" + dto.getInvoiceNo() + "|" + dto.getPrice() + "|" + dto.getFromcountry()));

        List<InvoiceDataDTO> processedZyTo = new ArrayList<>();
        for (Map.Entry<String, List<InvoiceDataDTO>> entry : groupedZyTo.entrySet()) {
            List<InvoiceDataDTO> group = entry.getValue();
            InvoiceDataDTO first = group.get(0);
            InvoiceDataDTO newItem = new InvoiceDataDTO();
            BeanUtil.copyProperties(first, newItem);

            // 汇总数量
            int totalQty = group.stream()
                    .mapToInt(dto -> dto.getQty() != null ? dto.getQty() : 0)
                    .sum();
            newItem.setQty(totalQty);

            // 去重处理 -- 根据sku+invoiceId+sku+invoiceNo
            if (processedZyTo.stream().noneMatch(item ->
                    Objects.equals(item.getInvoiceId(), newItem.getInvoiceId()) &&
                            Objects.equals(item.getSku(), newItem.getSku()) &&
                            Objects.equals(item.getInvoiceNo(), newItem.getInvoiceNo()))) {
                newItem.setB(""); // B列设为空
                newItem.setBuyerTaxId(""); // 买方税号H设为空
                newItem.setBirthplace("CN"); // 原产地D设为CN
                processedZyTo.add(newItem);
            }
        }

        // 并且转运数据的invoiceNo 不能为空
        processedZyFrom = processedZyFrom.stream().filter(f -> StrUtil.isNotBlank(f.getInvoiceNo())).collect(Collectors.toList());
        processedZyTo = processedZyTo.stream().filter(f -> StrUtil.isNotBlank(f.getInvoiceNo())).collect(Collectors.toList());

        result.put("zy_from", processedZyFrom);
        result.put("zy_to", processedZyTo);
        return result;
    }

    /**
     * 添加海关编码
     */
    private List<InvoiceDataDTO> addHscode(List<InvoiceDataDTO> data, String belongs) {
        List<InvoiceDataDTO> hsCodeData;
        if ("costway-pl".equals(belongs)) {
            hsCodeData = dailyMetaStkShipmentMapper.getHscodeDataByBelongsIsCostwayPl();
        } else if ("costway-fr".equals(belongs)) {
            hsCodeData = dailyMetaStkShipmentMapper.getHscodeDataByBelongsIsCostwayFr();
        } else if ("costway-de".equals(belongs)) {
            hsCodeData = dailyMetaStkShipmentMapper.getHscodeDataByBelongsIsCostwayDe();
        } else if (belongs != null && belongs.startsWith("fds")) {
            hsCodeData = dailyMetaStkShipmentMapper.getHscodeDataByBelongsIsFds();
        } else {
            hsCodeData = dailyMetaStkShipmentMapper.getHscodeDataByBelongsIsAny();
        }
        if (!hsCodeData.isEmpty()) {
            // 使用LinkedHashMap保持插入顺序
            hsCodeData = new ArrayList<>(
                    hsCodeData.stream()
                            .collect(Collectors.toMap(
                                    InvoiceDataDTO::getSku,
                                    item -> item,
                                    (first, second) -> first,  // 冲突时保留第一个
                                    LinkedHashMap::new         // 保持插入顺序
                            )).values()
            );
        }

        Map<String, List<InvoiceDataDTO>> descriptionDataMap = hsCodeData.stream().collect(Collectors.groupingBy(InvoiceDataDTO::getSku));
        List<InvoiceDataDTO> mergeData = new ArrayList<>();
        for (InvoiceDataDTO mainItem : data) {
            String key = mainItem.getSku();
            if (descriptionDataMap.containsKey(key)) {
                List<InvoiceDataDTO> InvoiceDataDTOS = descriptionDataMap.get(key);
                InvoiceDataDTOS.forEach(f -> {
                    InvoiceDataDTO newItem = new InvoiceDataDTO();
                    BeanUtil.copyProperties(mainItem, newItem);
                    newItem.setHscode(f.getHscode());
                    mergeData.add(newItem);
                });
            } else {
                mergeData.add(mainItem);
            }
        }
        return mergeData;
    }

    /**
     * 添加异常海关编码
     */
    private List<InvoiceDataDTO> addAbnormalHscode(List<InvoiceDataDTO> data) {
        // 处理没有海关编码的数据
        List<InvoiceDataDTO> withHsCode = data.stream()
                .filter(dto -> dto.getHscode() != null)
                .collect(Collectors.toList());
        List<InvoiceDataDTO> withoutHsCode = data.stream()
                .filter(dto -> dto.getHscode() == null)
                .collect(Collectors.toList());
        List<InvoiceDataDTO> hsCodeData = dailyMetaStkShipmentMapper.getHscodeDataByBelongsIsNull();

        //左连接操作
        Map<String, List<InvoiceDataDTO>> hsCodeDataMap = hsCodeData.stream().collect(Collectors.groupingBy(InvoiceDataDTO::getSku));

        List<InvoiceDataDTO> addHsCodeData = new ArrayList<>();
        for (InvoiceDataDTO mainItem : withoutHsCode) {
            String key = mainItem.getSku();
            if (hsCodeDataMap.containsKey(key)) {
                List<InvoiceDataDTO> InvoiceDataDTOS = hsCodeDataMap.get(key);
                InvoiceDataDTOS.forEach(f -> {
                    InvoiceDataDTO newItem = new InvoiceDataDTO();
                    BeanUtil.copyProperties(mainItem, newItem);
                    newItem.setHscode(f.getHscode());
                    addHsCodeData.add(newItem);
                });
            } else {
                addHsCodeData.add(mainItem);
            }
        }

        List<InvoiceDataDTO> AllHsCode = new ArrayList<>();
        AllHsCode.addAll(withHsCode);
        AllHsCode.addAll(addHsCodeData);
        return AllHsCode;
    }

    /**
     * 添加税号
     */
    private List<InvoiceDataDTO> addTaxid(List<InvoiceDataDTO> data) {
        List<InvoiceDataDTO> taxIdData = dailyMetaCorpHeaderMapper.getTaxid();
        taxIdData.forEach(dto -> dto.setCorp(dto.getCorp().toLowerCase()));

        // 使用LinkedHashMap保持插入顺序并去重
        Map<String, List<InvoiceDataDTO>> descriptionDataMap = taxIdData.stream().collect(Collectors.groupingBy(InvoiceDataDTO::getCorp));
        List<InvoiceDataDTO> buyerTaxid = new ArrayList<>();
        for (InvoiceDataDTO mainItem : data) {
            String key = mainItem.getFullbuyer();
            if (descriptionDataMap.containsKey(key)) {
                List<InvoiceDataDTO> InvoiceDataDTOS = descriptionDataMap.get(key);
                InvoiceDataDTOS.forEach(f -> {
                    InvoiceDataDTO newItem = new InvoiceDataDTO();
                    BeanUtil.copyProperties(mainItem, newItem);
                    newItem.setBuyerTaxId(f.getTaxid());
                    buyerTaxid.add(newItem);
                });
            } else {
                buyerTaxid.add(mainItem);
            }
        }
        return buyerTaxid;
    }

    /**
     * 添加信息
     */
    public List<InvoiceDataDTO> addInfos(List<InvoiceDataDTO> data, String currentDate, String belong) {
        data.forEach(f -> f.setDate(currentDate));

        List<InvoiceDataDTO> addHscodeData = addHscode(data, belong);
        List<InvoiceDataDTO> dataWithHscode = addHscodeData.stream()
                .filter(dto -> dto.getHscode() != null)
                .collect(Collectors.toList());
        List<InvoiceDataDTO> dataWithoutHscode = addHscodeData.stream()
                .filter(dto -> dto.getHscode() == null)
                .collect(Collectors.toList());
        // 清除没有海关编码的数据中的海关编码字段 -- 这里不需要置空，不使用即可

        List<InvoiceDataDTO> addOtherHscodeData = addHscode(dataWithoutHscode, "all");
        List<InvoiceDataDTO> addAbnormalHscodeData = addAbnormalHscode(addOtherHscodeData);

        List<InvoiceDataDTO> withHscode = new ArrayList<>(dataWithHscode);
        withHscode.addAll(addAbnormalHscodeData);

        if (data.size() != withHscode.size()) {
            log.error("数据不一致");
            throw new RuntimeException("数据不一致");
        }

        List<InvoiceDataDTO> weightData = dailyMetaProductMapper.getWeight();
        List<InvoiceDataDTO> uniqueWeightData = weightData.stream()
                .collect(Collectors.groupingBy(InvoiceDataDTO::getSku))
                .values()
                .stream()
                .map(list -> list.get(0))  // 只取每组的第一条记录
                .collect(Collectors.toList());

        Map<String, List<InvoiceDataDTO>> descriptionDataMap = uniqueWeightData.stream().collect(Collectors.groupingBy(InvoiceDataDTO::getSku));
        List<InvoiceDataDTO> withWeight = new ArrayList<>();
        for (InvoiceDataDTO mainItem : withHscode) {
            String key = mainItem.getSku();
            if (descriptionDataMap.containsKey(key)) {
                List<InvoiceDataDTO> InvoiceDataDTOS = descriptionDataMap.get(key);
                InvoiceDataDTOS.forEach(f -> {
                    InvoiceDataDTO newItem = new InvoiceDataDTO();
                    BeanUtil.copyProperties(mainItem, newItem);
                    newItem.setWeight(f.getWeight());
                    withWeight.add(newItem);
                });
            } else {
                withWeight.add(mainItem);
            }
        }

        return withWeight;
    }

    /**
     * 生成数据
     */
    public Map<String, List<InvoiceDataDTO>> generateData(String start, String end, String belong, String country) {
        Map<String, List<InvoiceDataDTO>> result = new HashMap<>();

        List<InvoiceDataDTO> cgTo = dealCg(start, end, belong);

        Map<String, List<InvoiceDataDTO>> zyData = dealZy(start, end, belong, country);
        List<InvoiceDataDTO> zyFrom = zyData.get("zy_from");
        List<InvoiceDataDTO> zyTo = zyData.get("zy_to");

        Map<String, List<InvoiceDataDTO>> b2bData = dealB2b(start, end, belong, country);
        List<InvoiceDataDTO> b2bFrom = b2bData.get("b2b_from");
        List<InvoiceDataDTO> b2bTo = b2bData.get("b2b_to");

        List<InvoiceDataDTO> fromData = new ArrayList<>();
        fromData.addAll(zyFrom);
        fromData.addAll(b2bFrom);
        fromData.forEach(f -> f.setLocation(f.getTocountry()));

        List<InvoiceDataDTO> toData = new ArrayList<>();
        toData.addAll(cgTo);
        toData.addAll(zyTo);
        toData.addAll(b2bTo);
        toData.forEach(f -> f.setLocation(f.getFromcountry()));


        result.put("from_data", fromData);
        result.put("to_data", toData);
        return result;
    }

}